package tw.com.hitevision.whiteboard.android.youtube.searchView;

import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.ColorInt;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;

import org.json.JSONArray;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import tw.com.hitevision.whiteboard.android.MainActivity;
import tw.com.hitevision.whiteboard.android.R;
import tw.com.hitevision.whiteboard.android.retrofit.RetrofitManager;
import tw.com.hitevision.whiteboard.android.widgets.ModifiedEditTextForSkia;
import tw.com.hitevision.whiteboard.android.youtube.searchView.fragment.YoutubeSearchDefaultFragment;
import tw.com.hitevision.whiteboard.android.youtube.searchView.fragment.YoutubeSearchResultFragment;


public class YoutubeSearchView extends RelativeLayout {

    private final String TAG = YoutubeSearchView.class.getSimpleName();
    private final Context context;
    private @ColorInt int focusedSearchTextColor;
    private ModifiedEditTextForSkia searchInput;
    private ImageView searchButton;
    private ConstraintLayout suggestionLayout;
    private Disposable suggestionDisposable;
    private YoutubeSuggestionAdapter youtubeSuggestionAdapter;
    private List<String> currentSuggestionList;
    private boolean isOnClick = false;

    public YoutubeSearchView(Context context) {
        super(context);
        init(context);
        this.context = context;
    }

    public YoutubeSearchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
        this.context = context;
    }

    public YoutubeSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
        this.context = context;
    }

    private void init(Context context) {
        inflate(context, R.layout.menu_youtube_search, this);

        View root = findViewById(R.id.youtube_search_view_layout);
        root.setOnTouchListener((v, event) -> {
            if (searchInput.isFocused()) {
                searchInput.clearFocus();
            }
            hideKeyboard();
            return true;
        });

        searchInput = findViewById(R.id.youtube_search_input);
        searchInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
        focusedSearchTextColor = getResources().getColor(R.color.youtube_Video_search_input_hint_color);

        ImageView exitButton =  findViewById(R.id.youtube_search_exit_button);
        exitButton.setOnClickListener(v -> {
            setVisibility(View.GONE);
        });

        searchInput.setOnFocusChangeListener((v, hasFocus) -> {
            Log.d(TAG, "searchInput hasFocus:" + hasFocus);
            if (hasFocus) {
                searchInput.setTextColor(focusedSearchTextColor);
                searchInput.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.youtube_video_search_input_focus_background));
            } else {
                hideKeyboard();
                searchInput.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.youtube_video_search_input_unfocus_background));
            }
        });

        searchInput.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_GO) {
                Log.d(TAG, "searchInput:" + searchInput.getText().toString());
            }
            return false;
        });

        searchInput.setUsingInSearchImage(true);
        searchInput.addTextChangedListener(textWatcher);
        searchInput.setOnKeyListener(onKeyListener);

        suggestionLayout = findViewById(R.id.youtube_search_suggestion_layout);
        RecyclerView suggestionRecyclerView = findViewById(R.id.youtube_search_suggestion_recycler_view);
        currentSuggestionList = new ArrayList<>();
        youtubeSuggestionAdapter = new YoutubeSuggestionAdapter(currentSuggestionList, suggestionListener);
        suggestionRecyclerView.setAdapter(youtubeSuggestionAdapter);

        searchButton = findViewById(R.id.youtube_search_button);
        searchButton.setOnClickListener(searchClickLis);

        // clear all fragment
        for (Fragment fragment : ((MainActivity)context).getSupportFragmentManager().getFragments()) {
            ((MainActivity)context).getSupportFragmentManager().beginTransaction().remove(fragment).commit();
        }

        FragmentManager fragmentManager = ((MainActivity)context).getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.youtube_search_fragment, YoutubeSearchDefaultFragment.getInstance());
        fragmentTransaction.commit();
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (visibility == VISIBLE && searchInput != null) {
            searchInput.setText("");
            searchInput.setFocusable(true);
            searchInput.requestFocus();
            searchInput.postDelayed(() -> {
                InputMethodManager keyboard = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                keyboard.showSoftInput(searchInput, InputMethodManager.SHOW_IMPLICIT);
            }, 100);
        }

        if (visibility == GONE) {
            currentSuggestionList.clear();
            if (suggestionDisposable!=null) {
                if (!suggestionDisposable.isDisposed()) {
                    suggestionDisposable.dispose();
                }
            }
            searchInput.clearFocus();
            hideKeyboard();
        }
    }

    private final YoutubeSuggestionAdapter.Listener suggestionListener = suggestion -> {
        Log.i(TAG, "suggestion onClick:" + suggestion);
        isOnClick = true;
        searchInput.setText(suggestion);
        searchInput.setSelection(Objects.requireNonNull(searchInput.getText()).length());
        if (suggestionLayout.getVisibility() == View.VISIBLE) {
            suggestionLayout.setVisibility(View.GONE);
        }
    };

    private final TextWatcher textWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            Log.i(TAG, "beforeTextChanged s:" + s);
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Log.i(TAG, "onTextChanged s:" + s);
            if (isOnClick) {
                isOnClick = false;
                return;
            }
            if (suggestionDisposable != null) {
                if (!suggestionDisposable.isDisposed()) {
                    suggestionDisposable.dispose();
                }
            }
            String client = "firefox";
            String ds = "yt";
//            String hl = "tw";
            suggestionDisposable = RetrofitManager.getSuggestInstance().getSuggestQueriesAPI().getSuggestByQueries(
                    s.toString(),
                    client,
                    ds,
                    null)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(result -> {
                        String responseBody = result.string();
                        JSONArray resultArray = new JSONArray(responseBody);
                        Log.i(TAG, "searchKeyword:" + resultArray.get(0));
                        JSONArray suggestArray = new JSONArray(resultArray.get(1).toString());
                        currentSuggestionList.clear();
                        youtubeSuggestionAdapter.submitList(currentSuggestionList);
                        youtubeSuggestionAdapter.notifyDataSetChanged();
                        if (suggestArray.length() > 0) {
                            for (int i = 0; i < suggestArray.length(); i++) {
                                String suggestion = String.valueOf(suggestArray.get(i));
                                currentSuggestionList.add(suggestion);
                                Log.i(TAG, "suggest[" + i + "]:" + suggestArray.get(i));
                            }
                            if (suggestionLayout.getVisibility() == View.GONE && currentSuggestionList.size() > 0) {
                                suggestionLayout.setVisibility(View.VISIBLE);
                            }
                        } else {
                            if (suggestionLayout.getVisibility() == View.VISIBLE) {
                                suggestionLayout.setVisibility(View.GONE);
                            }
                        }
                    }, throwable -> {
                        Log.e(TAG, "throwable:" + throwable.getMessage());
                        if (suggestionLayout.getVisibility() == View.VISIBLE) {
                            suggestionLayout.setVisibility(View.GONE);
                        }
                    });
        }

        @Override
        public void afterTextChanged(Editable s) {
            Log.i(TAG, "afterTextChanged s:" + s);
        }
    };

    private final OnClickListener searchClickLis = new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.youtube_search_button && searchInput.getText().length() > 0 && searchInput.getCurrentTextColor() == focusedSearchTextColor) {
                if (searchInput.isFocused()) {
                    searchInput.clearFocus();
                    hideKeyboard();
                }
                Log.d(TAG, "searchInput:" + searchInput.getText().toString());

                FragmentManager fragmentManager = ((MainActivity)context).getSupportFragmentManager();
                Fragment fragment = fragmentManager.findFragmentById(R.id.youtube_search_fragment);
                if (fragment instanceof YoutubeSearchResultFragment) {
                    ((YoutubeSearchResultFragment)fragment).getSearchVideoList(searchInput.getText().toString());
                } else {
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.replace(R.id.youtube_search_fragment, YoutubeSearchResultFragment.getInstance(searchInput.getText().toString()));
                    fragmentTransaction.commit();
                }
            }
        }
    };

    private final OnKeyListener onKeyListener = (v, keyCode, event) -> {
        if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
            searchButton.performClick();
            return true;
        }
        return false;
    };

    public void toggleWebView(boolean toggle) {
        if (toggle) {
            this.setVisibility(View.VISIBLE);
        } else {
            searchInput.clearFocus();
            hideKeyboard();
            this.setVisibility(View.GONE);
        }
    }

    public void hideKeyboard() {
        if (suggestionLayout.getVisibility() == View.VISIBLE) {
            suggestionLayout.setVisibility(View.GONE);
        }
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(searchInput.getWindowToken(), 0);
        }
    }
}
